package com.pktechan.manage.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

/**
 * <br>
 * <b>功能：</b>日期应用类<br>
 * <b>作者：</b>Wang Jiahao<br>
 * <b>日期：</b> Nov 9, 2014 <br>
 */
public class DateUtil {
    private final static Logger log = LoggerFactory.getLogger(DateUtil.class);

    public static SimpleDateFormat sdfShort = new SimpleDateFormat(
            "yyyyMMdd");
    static SimpleDateFormat sdfLong = new SimpleDateFormat(
            "yyyy-MM-dd");
    static SimpleDateFormat sdfLongCn = new SimpleDateFormat(
            "yyyy年MM月dd日");
    static SimpleDateFormat sdfShortU = new SimpleDateFormat(
            "MMM dd", Locale.ENGLISH);
    static SimpleDateFormat sdfLongU = new SimpleDateFormat(
            "MMM dd,yyyy", Locale.ENGLISH);
    static SimpleDateFormat sdfLongTime = new SimpleDateFormat(
            "yyyyMMddHHmmss");
    static SimpleDateFormat sdfLongTimePlus = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");
    static SimpleDateFormat sdfShortLongTimePlusCn = new SimpleDateFormat(
            "yyyy年MM月dd日 HH:mm");
    static SimpleDateFormat sdfLongTimePlusMill = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss:SSSS");
    static SimpleDateFormat sdfMd = new SimpleDateFormat(
            "MM月dd日");
    static SimpleDateFormat sdfTimeShort = new SimpleDateFormat(
            "HHmmss");
    static SimpleDateFormat sdfShortYM = new SimpleDateFormat(
            "yyyyMM");
    private static long DAY_IN_MILLISECOND = 0x5265c00L;

    public DateUtil() {
    }


    /**
     * 通过身份证号码获取出生日期 (缺少验证 请确保证件有效 )
     *
     * @param certCode
     * @return 返回的出生日期格式：1990-01-01
     */
    public static String getBirthday(String certCode) {
        String birthday = "";
        if (certCode.length() == 15) {
            birthday = "19" + certCode.substring(6, 8) + "-"
                    + certCode.substring(8, 10) + "-"
                    + certCode.substring(10, 12);
        } else if (certCode.length() == 18) {
            birthday = certCode.substring(6, 10) + "-"
                    + certCode.substring(10, 12) + "-"
                    + certCode.substring(12, 14);
        } else {
            birthday = null;
        }
        return birthday;
    }

    /**
     * 通过身份证号码获取 性别 (缺少验证 请确保证件有效 )
     *
     * @param certCode
     * @return 性别格式：0-女，1-男
     */
    public static Integer getSex(String certCode) {
        Integer sexCode;
        if (certCode.length() == 15) {
            sexCode = Integer.parseInt(certCode.substring(certCode.length() - 3, certCode.length())) % 2 == 0 ? 0 : 1;
        } else if (certCode.length() == 18) {
            sexCode = Integer.parseInt(certCode.substring(certCode.length() - 4, certCode.length() - 1)) % 2 == 0 ? 0 : 1;
        } else {
            sexCode = null;
        }
        return sexCode;
    }


    /**
     * 根据日期 获取 X 年 的今天
     *
     * @param date
     * @param iYear
     * @return String yyyy年MM月dd日
     */
    public static String getDateYear(Date date, int iYear) {
        Calendar rightNow = Calendar.getInstance();
        rightNow.setTime(date);
        rightNow.add(Calendar.YEAR, +1);
        Date dateYear = rightNow.getTime();
        return DateUtil.getDateLongCn(dateYear);
    }


    /**
     * @return String
     * @throws Exception
     * @author
     * @Descrption get Date format
     * Example：2008-05-15
     */
    public static String getDateLong(Date date) throws Exception {
        String nowDate = "";
        try {
            if (date != null)
                nowDate = sdfLong.format(date);
            return nowDate;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new Exception(e.getMessage());
        }
    }

    /**
     * @return String
     * @throws Exception
     * @author
     * @Descrption get Date format
     * Example：2008-05-15
     */
    public static String getTimeShort(Date date) throws Exception {
        String nowDate = "";
        try {
            if (date != null)
                nowDate = sdfTimeShort.format(date);
            return nowDate;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new Exception(e.getMessage());
        }
    }

    /**
     * @return String
     * @throws Exception
     * @author
     * @Descrption get Date format
     * Example：2008-05-15
     */
    public static String getDateShort(Date date) throws Exception {
        String nowDate = "";
        try {
            if (date != null)
                nowDate = sdfShort.format(date);
            return nowDate;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new Exception(e.getMessage());
        }
    }

    /**
     * @return String
     * @throws Exception
     * @author Pablo
     * @Descrption:ȡ�õ�ǰ����getgetg get Date format
     * Example：2008年-05月-15日
     */
    public static String getDateLongCn(Date date) {
        String nowDate = "";
        try {
            if (date != null)
                nowDate = sdfLongCn.format(date);
            return nowDate;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return "";
        }
    }

    /**
     * @return String
     * @throws Exception
     * @author vowo Descrption:ȡ�õ�ǰ����getgetg get Date format Example：05月-15日
     */
    public static String getDateMD(Date date) {
        String nowDate = "";
        try {
            if (date != null)
                nowDate = sdfMd.format(date);
            return nowDate;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return "";
        }
    }

    /**
     * @return String
     * @throws Exception
     * @author Pablo Descrption:ȡ�õ�ǰ����getgetg get Date format
     * Example：2008年-05月-15日 11:05
     */
    public static String getDateShortLongTimeCn(Date date) {
        String nowDate = "";
        try {
            if (date != null)
                nowDate = sdfShortLongTimePlusCn.format(date);
            return nowDate;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return "";
        }
    }

    /**
     * @return String
     * @throws Exception
     * @author Pablo Descrption:ȡ�õ�ǰ����getgetg get Date format Example：Aug 28,
     * 2007
     */
    public static String getDateUS(Date date) {
        String nowDate = "";
        try {
            if (date != null)
                nowDate = sdfLongU.format(date);
            return nowDate;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return "";
        }
    }

    /**
     * @return String
     * @throws Exception
     * @author Pablo Descrption:ȡ�õ�ǰ����getgetg get Date format Example：Aug 28,
     * 2007
     */
    public static String getDateUSShort(Date date) {
        String nowDate = "";
        try {
            if (date != null)
                nowDate = sdfShortU.format(date);
            return nowDate;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return "";
        }
    }

    /**
     * 简单转换日期类型到字符串类型，本地信息设为UK
     *
     * @param date
     * @param format
     * @return String
     */
    public static String getFormatDate(Date date, String format) {
        try {
            return new SimpleDateFormat(format, Locale.UK).format(date);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return (date == null) ? new Date().toString() : date.toString();
        }
    }

    /**
     * Descrption:取得当前日期时间,格式为:YYYYMMDDHHMISS
     *
     * @return String
     * @throws Exception
     */
    public static String getNowLongTime() throws Exception {
        String nowTime = "";
        try {
            java.sql.Date date = null;
            date = new java.sql.Date(new Date().getTime());
            nowTime = sdfLongTime.format(date);
            return nowTime;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw e;
        }
    }

    /**
     * Descrption:取得当前日期,格式为:YYYYMMDD
     *
     * @return String
     * @throws Exception
     */
    public static String getNowShortDate() {
        String nowDate = "";
        try {
            java.sql.Date date = null;
            date = new java.sql.Date(new Date().getTime());
            nowDate = sdfShort.format(date);
            return nowDate;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return "";
        }
    }

    /**
     * Descrption:取得当前日期,格式为:YYYY-MM-DD
     *
     * @return String
     * @throws Exception
     */
    public static String getNowFormatDate() throws Exception {
        String nowDate = "";
        try {
            java.sql.Date date = null;
            date = new java.sql.Date(new Date().getTime());
            nowDate = sdfLong.format(date);
            return nowDate;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw e;
        }
    }

    /**
     * Descrption:取得当前日期,格式为:yyyy-MM-dd HH:mm:ss
     *
     * @return String
     * @throws Exception
     */
    public static String getNowPlusTime() throws Exception {
        String nowDate = "";
        try {
            java.sql.Date date = null;
            date = new java.sql.Date(new Date().getTime());
            nowDate = sdfLongTimePlus.format(date);
            return nowDate;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw e;
        }
    }

    /**
     * Descrption:取得当前日期,格式为:yyyy-MM-dd HH:mm:ss
     *
     * @return String
     * @throws Exception
     */
    public static String getPlusTime(Date date) throws Exception {
        if (date == null)
            return null;
        try {
            String nowDate = sdfLongTimePlus.format(date);
            return nowDate;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw e;
        }
    }

    /**
     * Descrption:取得当前日期到毫秒极,格式为:yyyyMMddHHmmssSSSS
     *
     * @return String
     * @throws Exception
     */
    public static String getNowPlusTimeMill() {
        return getPlusTimeMill(new Date());
    }

    /**
     * Descrption:取得当前日期到毫秒极,格式为:yyyyMMddHHmmssSSSS
     *
     * @return String
     * @throws Exception
     */
    public static String getPlusTimeMill(Date date) {
        String nowDate = "";
        try {
            nowDate = sdfLongTimePlusMill.format(date);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            //throw e;
        }
        return nowDate;
    }

    /**
     * 得到当前月份值:12
     *
     * @return String
     * @throws Exception
     */
    public static String getNowMonth() throws Exception {
        String nowMonth = "";
        try {
            String strTemp = getNowLongTime();
            nowMonth = strTemp.substring(4, 6);
            return nowMonth;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw e;
        }
    }


    /**
     * 得到当前小时值:23
     *
     * @return String
     * @throws Exception
     */
    public static String getNowHour() throws Exception {
        String nowHour = "";
        try {
            String strTemp = getNowPlusTimeMill();
            nowHour = strTemp.substring(8, 10);
            return nowHour;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 获取当前日期为日期型
     *
     * @return 当前日期，java.util.Date类型
     */
    public static Date getCurrentDate() {
        Calendar cal = Calendar.getInstance();

        // String currentDate = null;
        Date d = cal.getTime();

        return d;
    }

    /**
     * 获取当前年月的字符串
     *
     * @return 当前年月，yyyyMM格式
     */
    public static String getCurrentYearMonth() {
        Calendar cal = Calendar.getInstance();
        String currentYear = (new Integer(cal.get(Calendar.YEAR))).toString();
        String currentMonth = null;
        if (cal.get(Calendar.MONTH) < 9)
            currentMonth = "0"
                    + (new Integer(cal.get(Calendar.MONTH) + 1)).toString();
        else
            currentMonth = (new Integer(cal.get(Calendar.MONTH) + 1))
                    .toString();
        return (currentYear + currentMonth);
    }

    /**
     * 获取当前年为整型
     *
     * @return 获取当前日期中的年，int型
     */
    public static int getCurrentYear() {
        Calendar cal = Calendar.getInstance();
        int currentYear = cal.get(Calendar.YEAR);
        return currentYear;
    }

    /**
     * 获取当前月为整型
     *
     * @return 获取当前日期中的月，int型
     */
    public static int getCurrentMonth() {
        Calendar cal = Calendar.getInstance();
        int currentMonth = cal.get(Calendar.MONTH);
        return currentMonth + 1;
    }

    /**
     * 根据身份证号码获取年龄
     *
     * @param id 身份证号
     * @return int - 年龄
     * @throws Exception 身份证号错误时发生
     */
    public static int getAge(String id) throws Exception {
        int age = -1;
        int length = id.length();
        String birthday = "";
        if (length == 15) {
            birthday = id.substring(6, 8);
            birthday = "19" + birthday;
        } else if (length == 18) {
            birthday = id.substring(6, 10);
        } else {
            throw new Exception("错误的身份证号");
        }
        int currentYear = Calendar.getInstance().get(Calendar.YEAR);
        age = currentYear - (new Integer(birthday)).intValue();
        return age;
    }

    /**
     * 根据年龄获取出生年份
     *
     * @param age int 年龄
     * @return Date - 出生年份
     */
    public static java.sql.Date getDateByAge(int age) {
        Calendar calendar = Calendar.getInstance(Locale.CHINESE);
        long current = calendar.getTimeInMillis();
        calendar.set(calendar.get(Calendar.YEAR) - age,
                calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE));
        return new java.sql.Date((calendar.getTimeInMillis()));
    }


    /**
     * 取得与原日期相差一定天数的日期，返回Date型日期
     *
     * @param date       原日期
     * @param intBetween 相差的天数
     * @return date加上intBetween天后的日期
     */
    public static Date getDateBetween(Date date, int intBetween) {
        Calendar calo = Calendar.getInstance();
        calo.setTime(date);
        calo.add(Calendar.DATE, intBetween);
        return calo.getTime();
    }


    /**
     * 得到将年月型字符串增加1月后的日期字符串
     *
     * @param yearMonth yyyyMM格式
     * @return yearMonth增加一个月后的日期，yyyyMM格式
     */
    public static String increaseYearMonth(String yearMonth) {
        int year = (new Integer(yearMonth.substring(0, 4))).intValue();
        int month = (new Integer(yearMonth.substring(4, 6))).intValue();
        month = month + 1;
        if (month <= 12 && month >= 10)
            return yearMonth.substring(0, 4) + (new Integer(month)).toString();
        else if (month < 10)
            return yearMonth.substring(0, 4) + "0"
                    + (new Integer(month)).toString();
        else
            // if(month>12)
            return (new Integer(year + 1)).toString() + "0"
                    + (new Integer(month - 12)).toString();

    }

    /**
     * 得到将年月型字符串增加指定月数后的日期字符串
     *
     * @param yearMonth yyyyMM格式日期
     * @param addMonth  增加指定月数
     * @return yearMonth 增加addMonth个月后的日期，yyyyMM格式
     */
    public static String increaseYearMonth(String yearMonth, int addMonth) {
        int year = (new Integer(yearMonth.substring(0, 4))).intValue();
        int month = (new Integer(yearMonth.substring(4, 6))).intValue();
        month = month + addMonth;
        year = year + month / 12;
        month = month % 12;
        if (month <= 12 && month >= 10)
            return year + (new Integer(month)).toString();
        else
            return year + "0" + (new Integer(month)).toString();

    }

    /**
     * 取得当前日期的下一个月的第一天 add by yaojp 2002-10-08
     *
     * @return 当前日期的下个月的第一天，格式为yyyyMMDD
     */
    public static String getFirstDayOfNextMonth() {
        try {
            return increaseYearMonth(getNowShortDate().substring(0, 6)) + "01";
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return "";
        }
    }

    /**
     * 取得当前日期的下一个月的第一天 add by zhouning 2006-09-13
     *
     * @return 当前日期的下个月的第一天，格式为yyyyMMDD
     */
    public static String getFirstDayOfThisMonth() {
        try {
            return getNowShortDate().substring(0, 6) + "01";
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return "";
        }
    }


    /**
     * 得到将date增加指定月数后的date
     *
     * @param date       日期
     * @param intBetween 增加的月份
     * @return date 加上intBetween月数后的日期
     */
    public static Date increaseMonth(Date date, int intBetween) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, intBetween);
        return calendar.getTime();
    }

    /**
     * 得到将date增加指定天数后的date
     *
     * @param date       日期
     * @param intBetween 增加的天数
     * @return date 加上intBetween天数后的日期
     */
    public static Date increaseDay(Date date, int intBetween) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, intBetween);
        return calendar.getTime();
    }

    /**
     * 得到将date增加指定年数后的date
     *
     * @param date       日期
     * @param intBetween 增加的年数
     * @return date加上intBetween年数后的日期
     */
    public static Date increaseYear(Date date, int intBetween) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, intBetween);
        return calendar.getTime();
    }

    /**
     * 比较两个时间先后
     *
     * @param str1 传入的字符串
     * @param str2 传入的字符串
     * @return int negative integer, zero, or a positive integer as str1 is less
     * than, equal to, or greater than str2
     */
    public static int compareDate(String str1, String str2) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Date date1 = null, date2 = null;
        try {
            date1 = formatter.parse(str1);
            date2 = formatter.parse(str2);
        } catch (ParseException e) {
            log.error(e.getMessage(), e);
        }
        return date1.compareTo(date2);
    }

    /**
     * 比较两个时间先后
     *
     * @param str1 传入的字符串
     * @param str2 传入的字符串
     * @return int negative integer, zero, or a positive integer as str1 is less
     * than, equal to, or greater than str2
     */
    public static int compareDate(SimpleDateFormat formatter, String str1, String str2) {
        Date date1 = null, date2 = null;
        try {
            date1 = formatter.parse(str1);
            date2 = formatter.parse(str2);
        } catch (ParseException e) {
            log.error(e.getMessage(), e);
        }
        return date1.compareTo(date2);
    }

    /**
     * 得到当前日期，格式yyyy-MM-dd。
     *
     * @return String 格式化的日期字符串
     */
    public static String getToday() {
        Date cDate = new Date();
        SimpleDateFormat cSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return cSimpleDateFormat.format(cDate);
    }

    /**
     * 得到当前日期，格式yyyy-MM-dd。
     *
     * @return String 格式化的日期字符串
     */
    public static String getYesterday() {
        Date cDate = new Date();
        cDate.setTime(cDate.getTime() - 24 * 3600 * 1000);
        SimpleDateFormat cSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return cSimpleDateFormat.format(cDate);
    }

    /**
     * 得到当前日期，格式yyyy-MM-dd。
     *
     * @return String 格式化的日期字符串
     */
    public static String getTomorrow() {
        Date cDate = new Date();
        cDate.setTime(cDate.getTime() + 24 * 3600 * 1000);
        SimpleDateFormat cSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return cSimpleDateFormat.format(cDate);
    }

    /**
     * 得到当前日期时间,格式为yyyy-MM-dd hh:mm:ss.
     *
     * @return String
     */
    public static String getCurrDateTime() {
        Timestamp date = new Timestamp(
                System.currentTimeMillis());
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return formatter.format(date);
    }

    /**
     * 得出两个日期之间的间隔天数
     *
     * @param strFromDate 格式为yyyyMMdd
     * @param strToDate   格式为yyyyMMdd
     * @return int
     */
    public static int getBetweenDays(String strFromDate, String strToDate) {
        try {
            Calendar clFrom = new GregorianCalendar();
            int iYear = Integer.parseInt(strFromDate.substring(0, 4));
            int iMonth = Integer.parseInt(strFromDate.substring(4, 6));
            int iDay = Integer.parseInt(strFromDate.substring(6, 8));
            clFrom.set(iYear, iMonth, iDay, 0, 0, 0);
            Calendar clTo = new GregorianCalendar();
            iYear = Integer.parseInt(strToDate.substring(0, 4));
            iMonth = Integer.parseInt(strToDate.substring(4, 6));
            iDay = Integer.parseInt(strToDate.substring(6, 8));
            clTo.set(iYear, iMonth, iDay, 0, 0, 0);
            long llTmp = clTo.getTime().getTime() - clFrom.getTime().getTime();
            return new Long(llTmp / 1000 / 3600 / 24).intValue();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Integer.MIN_VALUE;
        }
    }


    /**
     * @param format 日期格式
     * @return String
     * @author zhangyong
     */
    public static String toDayToStr(String format) {
        try {
            Date now = new Date();
            return DateToStr(now, format) + " " + getWeekOfDate(now);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

    /**
     * @param date
     * @param format 日期格式
     * @return String
     * @author zhangyong
     */
    public static String DateToStr(Date date, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            return sdf.format(date);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

    /**
     * @param date
     * @param days
     * @return DATE 型加具体的天数
     * @author zhangyong
     */
    public static Date dateAddDays(Date date, int days) {
        long now = date.getTime() + (long) days * DAY_IN_MILLISECOND;
        return new Date(now);
    }

    /**
     * @param date,
     * @param fFormatStr eg:yyyy-MM-dd HH:mm:ss
     * @return 将DATE 转换成字符性日期格式
     * @author zhangyong
     */
    public static String dateTypeToString(Date date, String fFormatStr) {
        // yyyy-MM-dd HH:mm:ss
        SimpleDateFormat dateformat = new SimpleDateFormat(fFormatStr);
        String strDate = dateformat.format(date);
        return strDate;
    }

    /**
     * @param fFormatStr yyyy-MM-dd
     * @author zhangyong
     * @获取当前的系统时间，并按照固定的格式初始话
     */
    public static String getStringOfNowDate(String fFormatStr) {
        String nowDateString = dateTypeToString(new Date(), fFormatStr);
        return nowDateString;
    }

    /**
     * 获取当前日期是星期几<br>
     *
     * @param dt
     * @return 当前日期是星期几
     */
    public static String getWeekOfDate(Date dt) {
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);

        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;

        return weekDays[w];
    }

}
